package com.telrob.bytevm.instruct;

import java.util.List;

import com.telrob.bytevm.compile.Instruct;
import com.telrob.bytevm.compile.ReplaceCode;
import com.telrob.bytevm.natives.Natives;
import com.telrob.bytevm.utils.Define;
import com.telrob.bytevm.utils.ToolUtils;
import com.telrob.bytevm.vm.Register;

public class CALL implements Instruct{
	public boolean isPseudo(String opt) {
		return false;
	}
	@Override
	public boolean isComplie(String opt) {
		if("call".equals(opt.toLowerCase())||"calln".equals(opt.toLowerCase())) {
			return true;
		}
		return false;
	}

	@Override
	public byte[] complie(String line,String[] param,int curretIndex,List<ReplaceCode>labelReplace) {
		byte[]data=null;
		if("calln".equals(param[0].toLowerCase())) {
			int index=Natives.getMethodIndex(param[1]);
			data=new byte[5];
			data[0]=Define.CALLN;
			byte[]addr=ToolUtils.int2bytes(index);
			data[1]=addr[0];
			data[2]=addr[1];
			data[3]=addr[2];
			data[4]=addr[3];
		}else if("call".equals(param[0].toLowerCase())) {
			data=new byte[5];
			data[0]=Define.CALL;
			ReplaceCode code=new ReplaceCode(param[1], curretIndex+1);
			labelReplace.add(code);
			//data[1]=0;
			//data[2]=0;
			//data[3]=0;
			//data[4]=0;
		}
		return data;
	}

	@Override
	public int isRun(byte opt) {
		if(opt==Define.CALLN||opt==Define.CALL) {
			return 5;
		}
		return -1;
	}

	@Override
	public void parseRun(Register R, byte opt, byte[] code) {
		if(opt==Define.CALLN) {
			int index=ToolUtils.getInt(code, R.PC+1);
			int temp=index;
			while(code[temp]!=0) {
				temp++;
			}
			byte[]names=new byte[temp-index];
			for(int i=index;i<temp;i++) {
				names[i-index]=code[i];
			}
			String neme=new String(names);
			Natives.call(neme, R, opt, code);
			//到下一条
			R.PC+=5;
		}else if(opt==Define.CALL) {
			//获取call的函数地址
			int index=ToolUtils.getInt(code, R.PC+1);
			//将下一条要执行的地址放入堆栈中
			byte[]nextAddress=ToolUtils.int2bytes(R.PC+5);
			code[R.SS+R.SP+0]=nextAddress[0];
			code[R.SS+R.SP+1]=nextAddress[1];
			code[R.SS+R.SP+2]=nextAddress[2];
			code[R.SS+R.SP+3]=nextAddress[3];
			//堆栈加4
			R.SP=R.SP+4;
			//跳转到函数地址
			R.PC=index;
		}
		
	}

}
